package com.ksd.common.handler;

import com.ksd.common.core.result.R;
import com.ksd.result.ErrorHandler;
import com.ksd.result.Result;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;


/**
 * 统一返回处理类
 * @author carlo
 * (basePackages = "cn.com.tcc.ofa.brr.controller")建议扫包。为什么？
 * 如果你项目中没有使用Swagger，你可以扫包也可以不扫。都是正常的。
 * 但是如果你项目使用了Swagger，因为Swagger本身也是一个springmvc的项目，他里面也是一个个http请求
 * 这个请求的时候如果你项目中配置了拦截器，或者一些通知类xxxAdvice，那么就会把Swagger都会进行拦截。
 * 就会造成Swagger失效。
 */
@RestControllerAdvice
public class ResultResponseHandler implements ResponseBodyAdvice<Object> {


    /**
     * 是否支持advice功能，true是支持 false是不支持
     *
     * @return boolean
     */
    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }


    /**
     * @param object             代表其实就是springmvc的请求的方法结果
     * @param methodParameter    methodParameter
     * @param mediaType          mediaType
     * @param aClass             aClass
     * @param serverHttpRequest  serverHttpRequest
     * @param serverHttpResponse serverHttpResponse
     * @return Object
     */
    @Override
    public Object beforeBodyWrite(Object object, MethodParameter methodParameter,
                                  MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass,
                                  ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        if (object instanceof ErrorHandler) {
            //如果返回的结果是一个异常的结果，就把异常返回的结构数据封装到RestData里面即可
            ErrorHandler errorHandler = (ErrorHandler) object;
            return R.fail(errorHandler.getCode(), errorHandler.getDesc());
        } else if(object instanceof Result<?> || object instanceof R<?>){
            //如果返回对象类型是Result/R，表示是一些特殊的返回需要在Controller类自定义返回code的
            return object;
        } else if (object instanceof String) {
            try {
                //因为springmvc数据转换器对String是有特殊处理 StringHttpMessageConverter
                return new ObjectMapper().writeValueAsString(R.data(object));
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return R.data(object);
    }


}
